#include <AreaLoader.h>

#include <Area.h>
#include <BaseObject.h>

#include <SDL.h>
#include <memory.h>

namespace Color
{
	unsigned MakeRGB(unsigned char r, unsigned char g, unsigned char b)
	{
		 return (r << 16) + (g << 8) + b;
	}
}

ColorKey::~ColorKey()
{
	std::map< unsigned, ObjectCreator* >::iterator iter;
	iter = data.begin();
	for(; iter != data.end(); ++iter)
		delete iter->second;
}

namespace AreaLoader
{

void LoadColorData(const std::string& filename, std::list< ColorData >& out_data)
{
	if(filename.empty())
		return;

	SDL_Surface* data = SDL_LoadBMP( filename.c_str() );
	if(!data)
	{
		std::cerr<<"Error loading file: "<<filename <<"\n";
		return;
	}

	std::list< ColorData > colordata;

	const unsigned pixelsize = 3;

	if( data->format->BytesPerPixel != pixelsize )
	{
		std::cerr<<"Error: must be a 24-bits-per-pixel bitmap. Load failed\n";
		SDL_FreeSurface(data);
		return;
	}
	
	if(SDL_MUSTLOCK(data))
	{
		SDL_LockSurface( data );
	}

	for(int y = 0; y < data->h; y++)
	{
		for(int x = 0; x < data->w; x++)
		{
			pixeltype color[3]={0,0,0};
			memcpy(color, 
			&((pixeltype*)data->pixels)[(y*data->pitch) + x*pixelsize],
			sizeof(pixeltype)*pixelsize);

			if(color[0] != 0 || color[1] != 0 || color[2] != 0)
			{
				int w = data->w;
				int h = data->h;
				float in_x = static_cast<float>(x);
				float in_y = static_cast<float>(y);
				
				if(w != Global::GameWorldSize.x || y != Global::GameWorldSize.y)
				{
					in_x = in_x / w;
					in_y = in_y / h;
					in_x *= Global::GameWorldSize.x;
					in_y *= Global::GameWorldSize.y;
				}

				colordata.push_back( ColorData(color[2],color[1],color[0], vec2(in_x,Global::GameWorldSize.y - in_y)));
			}			
		}
	}

	if( SDL_MUSTLOCK( data ) ) 
	{
		SDL_UnlockSurface( data ); 
	}

	SDL_FreeSurface(data);
	out_data = colordata;
}

void ImportDataToArea(Area* area, std::list< ColorData >& colordata, ColorKey& key)
{
	if(!area)
		return;

	if(colordata.empty())
		return;

	if(key.data.empty())
		return;

	std::list< ColorData >::iterator iter;
	iter = colordata.begin();
	for(; iter != colordata.end(); ++iter)
	{
		std::map< unsigned, ObjectCreator* >::iterator finder;
		finder = key.data.find( Color::MakeRGB( iter->r,iter->g,iter->b ) );
		if( key.data.end() != finder )
		{
			BaseObject* obj = finder->second->Create();
			obj->SetPosition( iter->loc );
		}
	}
}


}